﻿package{
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;	
	import flash.utils.Dictionary;
	
	public class MyLoader {
		var list:Dictionary;
		var path:String = '';
		private var info:Array = [];
		var pool:Dictionary;
		var max:int;
		private var urlReq:URLRequest;
		private var back:Function;
		private var wait:int,ready:int,errorSeq:int;
		private var urlDict:Dictionary,loaderDict:Dictionary
		function MyLoader(max:int = 7){
			urlReq = new URLRequest();
			list = new Dictionary();
			loaderDict = new Dictionary();
			urlDict = new Dictionary();
			pool = new Dictionary();
			pool['pic'] = [];
			pool['text'] = [];
			pool['binary'] = pool['text'];
			wait = 0;
			this.max = max;
		}
		function load(index:String,url:String = '',type = null){
			if(url == ''){
				url = index;
			}
			if(type == null){
				type  = getType(url);
			}
			info.push({'index':index,'url':this.path + url,'type':type});
		}
		function set callback(back:Function){
			list = new Dictionary();
			loaderDict = new Dictionary();
			this.back = back;
			wait = info.length
			ready = 0;
			var end:int = max < wait ? max : wait;
			for(var i:int = 0;i < end;i++){
				go(ready++);
			}
		}		
		private function reply(ldr,content,flag:Boolean){
			if(flag){
				ldr.unload();
				pool['pic'].push(ldr);
			}else{
				pool['text'].push(ldr);
			}
			
			replyon(loaderDict[ldr],content);
		}
		private function replyon(seq,content){
			list[info[seq].index] = content;
			urlDict[info[seq].url] = content;
			if(ready < info.length){
				go(ready++);
			}
			wait--;
			if(wait == 0){
				urlDict = new Dictionary();
				wait = 0;
				info.length = 0;
				back();
			}
		}
		private function go(seq:Number){
			errorSeq = seq;
			urlReq.url = info[seq].url;
			
			if(urlDict[urlReq.url] != null){
				replyon(seq,urlDict[urlReq.url]);
				return;
			}
			var loader = getLoader(info[seq].type,seq);
			if(info[seq].type != 'pic'){
				loader.dataFormat = info[seq].type;
			}
			loader.load(urlReq);
		}
		private function errorTip(e:Event){
			trace(info[errorSeq].url);
			wait = 0;
			info.length = 0;			
		}
		private function getType(url:String){
			var ns:Array = url.split('.');
			var ext:String = ns[ns.length - 1];
			switch(ext){
				case 'swf':
				case 'jpg':
				case 'gif':
				case 'png':
					return 'pic'
				case 'txt':
					return URLLoaderDataFormat.TEXT;
				default:
					return URLLoaderDataFormat.BINARY;
			}
		}
		private function getLoader(type:String,seq:int){
			var loader,fun:Function;
			if(pool[type].length > 0){
				loader = pool[type].pop();
			}else{
				if(type == 'pic'){
					loader = new Loader();
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e){reply(loader,loader.content,true)});
					loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorTip);
				}else{
					loader = new URLLoader();
					loader.dataFormat = URLLoaderDataFormat.TEXT;
					loader.addEventListener(Event.COMPLETE,function(e){reply(loader,loader.data,false)});
					loader.addEventListener(IOErrorEvent.IO_ERROR,errorTip);
				}
			}
			loaderDict[loader] = seq;
			return loader;
		}
	}
}